package com.qyb.demo.threadpool2;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;

/**
 * <strong>实现功能:</strong>
 * <p></p>
 *
 * @author 秦有宝
 * @version 1.0.0  2019/1/23 14:59
 */
public class ThreadPoolExecutorDemo {

    /**
     * 获取处理结果和异常
     */
    public static void demo1(){
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        Future<Object> future = executorService.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                throw new RuntimeException("exception in call~");// 该异常会在调用Future.get()时传递给调用者
            }
        });

        try {
            Object result = future.get();
        } catch (InterruptedException e) {
            // interrupt
        } catch (ExecutionException e) {
            // exception in Callable.call()
            e.printStackTrace();
        }
    }

    /**
     * 正确构造线程池
     */
    public static void demo2(){
        int poolSize = Runtime.getRuntime().availableProcessors() * 2;
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(512);
        RejectedExecutionHandler policy = new ThreadPoolExecutor.DiscardPolicy();
        ExecutorService executorService = new ThreadPoolExecutor(poolSize, poolSize,
                0, TimeUnit.SECONDS,
                queue,
                policy);


        List<Callable<Result>> solvers = new ArrayList<>();

        Callable<Result> task = null;

        // 确定每条线程的数据
        for (int i = 0; i < 10; i++) {
           /* task = new Callable<Result>() {
                @Override
                public Result call() throws Exception {
                    Result r = new Result();
                    System.out.println("线程：" + r);
                    return r;
                }
            };*/

            task = () -> {
                Result r = new Result();
                System.out.println("线程：" + Thread.currentThread().getName() + r);
                return r;
            };

            // 这里提交的任务容器列表和返回的Future列表存在顺序对应的关系
            solvers.add(task);
        }


        try {
            solve(executorService, solvers);
        } catch (InterruptedException e) {
            // interrupt
        } catch (ExecutionException e) {
            // exception in Callable.call()
            e.printStackTrace();
        }
    }


    private static void solve(Executor executor, Collection<Callable<Result>> solvers)
            throws InterruptedException, ExecutionException {

        CompletionService<Result> ecs = new ExecutorCompletionService<Result>(executor);// 构造器

        for (Callable<Result> s : solvers){
            // 提交所有任务
            ecs.submit(s);
        }
        int n = solvers.size();
        for (int i = 0; i < n; ++i) {// 获取每一个完成的任务
            Result r = ecs.take().get();
            if (r != null)
                use(r);
        }
    }

    private static void use(Result r){
        System.out.println("use：" + Thread.currentThread().getName() + r);
    }
}
